﻿using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using GSQ.BusinessEntities;
using GSQ.DataAccess.DataSetTableAdapters;

namespace GSQ.DataAccess
{
    public class RecibosPagosDA
    {
        private void InicializarAdaptadores()
        {
            this.cnn = new SqlConnection(Connection.GetConnectionString);
            cnn.Open();
            this.tr = cnn.BeginTransaction();

            AdapterMaster.Connection = cnn;
            AdapterMaster.Transaction = tr;

            AdapterDetaill.Connection = cnn;
            AdapterDetaill.Transaction = tr;

            vAdapterMaster.Connection = cnn;
            vAdapterMaster.Transaction = tr;

            vAdapterDetaill.Connection = cnn;
            vAdapterDetaill.Transaction = tr;

            AdapterUtilidades.Connection = cnn;
            AdapterUtilidades.Transaction = tr;

            AdapterClientes.Connection = cnn;
            AdapterClientes.Transaction = tr;

            AdapterFacturas.Connection = cnn;
            AdapterFacturas.Transaction = tr;

            AdapterFacturasDetalles.Connection = cnn;
            AdapterFacturasDetalles.Transaction = tr;

            AdapterVendedores.Connection = cnn;
            AdapterVendedores.Transaction = tr;
        }

        #region Variables

        #region TableAdapters
        private RECIBOS_PAGOSTableAdapter AdapterMaster = new RECIBOS_PAGOSTableAdapter();
        private RECIBOS_PAGOS_DETALLESTableAdapter AdapterDetaill = new RECIBOS_PAGOS_DETALLESTableAdapter();
        private V_RECIBOS_PAGOSTableAdapter vAdapterMaster = new V_RECIBOS_PAGOSTableAdapter();
        private V_RECIBOS_PAGOS_DETALLESTableAdapter vAdapterDetaill = new V_RECIBOS_PAGOS_DETALLESTableAdapter();
        private SECUENCIASTableAdapter AdapterSecuencias = new SECUENCIASTableAdapter();
        private UTILIDADESTableAdapter AdapterUtilidades = new UTILIDADESTableAdapter();
        private CLIENTESTableAdapter AdapterClientes = new CLIENTESTableAdapter();
        private FACTURASTableAdapter AdapterFacturas = new FACTURASTableAdapter();
        private FACTURAS_DETALLESTableAdapter AdapterFacturasDetalles = new FACTURAS_DETALLESTableAdapter();
        private VENDEDORESTableAdapter AdapterVendedores = new VENDEDORESTableAdapter();
        #endregion

        private DataSet.RECIBOS_PAGOSDataTable entitiesMaster;
        private DataSet.RECIBOS_PAGOS_DETALLESDataTable entitiesDetaill;
        private DataSet.SECUENCIASRow entitySecuencia;
        private DataSet.RECIBOS_PAGOSRow entityMaster;
        private DataSet.RECIBOS_PAGOS_DETALLESRow entityDetaill;
        private DataSet.FACTURASDataTable entitiesFacturas;
        private DataSet.FACTURAS_DETALLESDataTable entitiesFacturasDetalles;
        private DataSet.VENDEDORESDataTable entitiesVendedores;
        private SqlConnection cnn = null;
        private SqlTransaction tr = null;
        #endregion

        public decimal Insert(RECIBOS_PAGOS value)
        {
            bool InternalOpen = false;
            try
            {
                #region Inicializar Metodo
                if (this.cnn == null)
                {
                    InternalOpen = true;
                    InicializarAdaptadores();
                }
                #endregion

                #region Obtener y Ajustar secuencias
                if (value.ES_CONSIGNACION)//Buscar y ajustar valores de secuencias
                {
                    this.entitySecuencia = this.AdapterSecuencias.GetDataByID(13).FirstOrDefault();
                    this.AdapterSecuencias.SecuenciasUpdateCommand(13);
                }
                else
                {
                    this.entitySecuencia = this.AdapterSecuencias.GetDataByID(14).FirstOrDefault();
                    this.AdapterSecuencias.SecuenciasUpdateCommand(14);
                }
                #endregion

                #region Preparar RECIBOS_PAGOS encabezado
                entitiesMaster = new DataSet.RECIBOS_PAGOSDataTable(); // Inicializo la tabla priRECIBOS_PAGOSipal 
                entityMaster = entitiesMaster.NewRECIBOS_PAGOSRow(); // Inicializo la fila priRECIBOS_PAGOSipal apartir de la tabla priRECIBOS_PAGOSipal

                entityMaster.NRO_DOCUMENTO = entitySecuencia.VALUE + 1;// Asigno el valor de secueRECIBOS_PAGOSia mas 1
                entityMaster.ID_CLIENTE = value.ID_CLIENTE;
                entityMaster.ID_USUARIO = value.ID_USUARIO;
                entityMaster.ID_VENDEDOR = value.ID_VENDEDOR;
                entityMaster.ES_CONSIGNACION = value.ES_CONSIGNACION;
                entityMaster.FECHA = value.FECHA;
                if (value.REFERENCIA != null && value.REFERENCIA.Trim() != string.Empty)
                    entityMaster.REFERENCIA = value.REFERENCIA;
                entityMaster.M_TOTAL = value.M_TOTAL;
                entityMaster.M_DESCUENTO = value.M_DESCUENTO;
                entityMaster.ACTIVO = true;
                if (value.OBSERVACIONES != null && value.OBSERVACIONES.Trim() != string.Empty)
                    entityMaster.OBSERVACIONES = value.OBSERVACIONES;
                entitiesMaster.AddRECIBOS_PAGOSRow(entityMaster); //Agrego la fila priRECIBOS_PAGOSipal a la tabla priRECIBOS_PAGOSipal 
                this.AdapterMaster.Update(this.entitiesMaster);
                value.ID = entityMaster.ID;
                #endregion

                #region Ajustar Montos de Clientes
                DataSet.CLIENTESRow rwCliente = AdapterClientes.GetDataByID(value.ID_CLIENTE).FirstOrDefault();
                rwCliente.MONTO_ADEUDADO -= value.M_TOTAL;
                AdapterClientes.Update(rwCliente);
                #endregion

                #region Preparar Detalle
                if (value.RECIBOS_PAGOS_DETALLES.Count > 0)
                {
                    entitiesDetaill = new DataSet.RECIBOS_PAGOS_DETALLESDataTable();
                    foreach (RECIBOS_PAGOS_DETALLES rw in value.RECIBOS_PAGOS_DETALLES)
                    {
                        entityDetaill = entitiesDetaill.NewRECIBOS_PAGOS_DETALLESRow();

                        #region Ajustar monto pagado de facturas
                        this.entitiesFacturas = this.AdapterFacturas.GetDataByID(rw.ID_FACTURA);
                        this.entitiesFacturas.FirstOrDefault().M_PAGADO += rw.MONTO;
                        this.AdapterFacturas.Update(this.entitiesFacturas);
                        #endregion

                        entityDetaill.ID = entityMaster.ID;
                        entityDetaill.ID_FACTURA = rw.ID_FACTURA;
                        entityDetaill.DESCUENTO = rw.DESCUENTO;
                        entityDetaill.X_DESCUENTO = rw.X_DESCUENTO;
                        entitiesDetaill.AddRECIBOS_PAGOS_DETALLESRow(entityDetaill);
                    }
                    this.AdapterFacturasDetalles.Update(this.entitiesFacturasDetalles);
                    this.AdapterDetaill.Update(this.entitiesDetaill);
                }
                else
                    throw new ArgumentException("Debe agregar facturas al detalle del recibo de pago");
                #endregion

                this.tr.Commit();
            }
            catch
            {
                if (InternalOpen)
                    tr.Rollback();
                throw;
            }
            finally
            {
                if (InternalOpen && this.cnn.State != System.Data.ConnectionState.Closed)
                    this.cnn.Close();
            }
            return value.ID;
        }

        public decimal Update(RECIBOS_PAGOS newValue, RECIBOS_PAGOS oldValue)
        {
            throw new NotImplementedException();
            //using (SqlConnection cnn = new SqlConnection(Connection.GetConnectionString))
            //{
            //    try
            //    {
            //        cnn.Open(); // abro la conexion
            //        AdapterMaster.Connection = cnn; // asignar la conexion al tableAdapter priRECIBOS_PAGOSipal

            //        SqlTransaction tr = cnn.BeginTransaction(); // Creo la transaccion y la inicializo con la conexion
            //        AdapterMaster.Transaction = tr; // Asigno  la transaccion al tableAdapter priRECIBOS_PAGOSipal

            //        entitiesMaster = this.AdapterMaster.GetDataByID(oldValue.ID);
            //        entityMaster = this.entitiesMaster.FirstOrDefault(); // Inicializo la fila priRECIBOS_PAGOSipal apartir de la tabla priRECIBOS_PAGOSipal

            //        entityMaster.ID_CONDICION = newValue.ID_CONDICION;
            //        entityMaster.TIPO = newValue.TIPO;
            //        entityMaster.ID_USUARIO = newValue.ID_USUARIO;
            //        entityMaster.FECHA = newValue.FECHA;
            //        entityMaster.F_VERECIBOS_PAGOSIMIENTO = newValue.F_VERECIBOS_PAGOSIMIENTO;
            //        entityMaster.ID_SUPLIDOR = newValue.ID_SUPLIDOR;
            //        entityMaster.NRO_FACTURA = newValue.NRO_FACTURA;
            //        if (newValue.RECIBOS_PAGOSF != null && newValue.RECIBOS_PAGOSF != string.Empty)
            //            entityMaster.RECIBOS_PAGOSF = newValue.RECIBOS_PAGOSF;
            //        if (newValue.OBSERVACIONES != null && newValue.OBSERVACIONES != string.Empty)
            //            entityMaster.OBSERVACIONES = newValue.OBSERVACIONES;
            //        entityMaster.ACTIVO = newValue.ACTIVO;

            //        try
            //        {
            //            AdapterMaster.Update(entitiesMaster); // Ejecuto la operacion de update para insertar el eRECIBOS_PAGOSabezado 

            //            AdapterDetaill.Connection = cnn; // Asigno la conexion al tableAdapter de detalle 
            //            AdapterDetaill.Transaction = tr; // Asigno la transaccion al tableAdapter de detalle                        

            //            DataSet.UTILIDADESRow utilidades = new DataSetTableAdapters.UTILIDADESTableAdapter { Connection = cnn, Transaction = tr }.GetData().FirstOrDefault();

            //            AdapterProductos.Connection = cnn;
            //            AdapterProductos.Transaction = tr;


            //            DataSet.COMPRAS_DETALLESDataTable comprasDetalles = AdapterDetaill.GetDataByID(oldValue.ID);
            //            foreach (DataSet.COMPRAS_DETALLESRow r in comprasDetalles)
            //            {
            //                AdapterProductos.ProductosUpdateExisteRECIBOS_PAGOSia((r.CANTIDAD * -1), r.ID_PRODUCTO);
            //            }
            //            AdapterDetaill.DeleteByID(oldValue.ID);
            //            entitiesDetaill = new DataSet.COMPRAS_DETALLESDataTable();

            //            foreach (COMPRAS_DETALLES rw in newValue.COMPRAS_DETALLES)
            //            {
            //                entityDetaill = entitiesDetaill.NewCOMPRAS_DETALLESRow();
            //                AdapterProductos.ProductosUpdateExisteRECIBOS_PAGOSia(rw.CANTIDAD, rw.ID_PRODUCTO);
            //                DataSet.PRODUCTOSRow producto = AdapterProductos.GetDataByID(rw.ID_PRODUCTO).FirstOrDefault();
            //                entityDetaill.COSTO_ANTERIOR = producto.COSTO;
            //                entityDetaill.PRECIO_ANTERIOR = producto.PRECIO;
            //                if (utilidades.AJUSTAR_PRECIOS_COSTO_COMPRAS)
            //                {
            //                    producto.COSTO = rw.COSTO;
            //                    producto.PRECIO = rw.COSTO + ((rw.COSTO * producto.X_GANARECIBOS_PAGOSIA) / 100);
            //                    AdapterProductos.Update(producto);
            //                }



            //                entityDetaill.ID = entityMaster.ID;
            //                entityDetaill.ID_PRODUCTO = rw.ID_PRODUCTO;
            //                entityDetaill.CANTIDAD = rw.CANTIDAD;
            //                entityDetaill.COSTO = rw.COSTO;
            //                entityDetaill.PRECIO = rw.PRECIO;
            //                entityDetaill.DESCUENTO = rw.DESCUENTO;
            //                entityDetaill.X_DESCUENTO = rw.X_DESCUENTO;
            //                entityDetaill.IMPUESTO = rw.IMPUESTO;
            //                entityDetaill.X_IMPUESTO = rw.X_IMPUESTO;
            //                entityDetaill.C_DEVUELTA = rw.C_DEVUELTA;
            //                entitiesDetaill.AddCOMPRAS_DETALLESRow(entityDetaill);
            //            }
            //            AdapterDetaill.Update(entitiesDetaill);
            //            tr.Commit();
            //        }
            //        catch (Exception ex)
            //        {
            //            tr.Rollback();
            //            throw ex;
            //        }

            //        newValue.ID = entityMaster.ID;
            //        return newValue.ID;
            //    }
            //    finally
            //    {
            //        if (cnn.State != System.Data.ConnectionState.Closed)
            //            cnn.Close();
            //    }
            //}
        }

        public RECIBOS_PAGOS GetById(decimal id)
        {
            bool InternalOpen = false;
            try
            {
                #region Inicializar Metodo
                if (this.cnn == null)
                {
                    InternalOpen = true;
                    InicializarAdaptadores();
                }
                #endregion

                DataSet.V_RECIBOS_PAGOSRow rw = this.vAdapterMaster.GetDataByID(id).FirstOrDefault();
                RECIBOS_PAGOS recibosPagos = null;
                if (rw != null)
                {
                    recibosPagos = GetEntity(rw, vAdapterDetaill.GetDataByID(rw.ID));
                    if (recibosPagos != null)
                    {
                        var facturasDA = new FacturasDA();
                        foreach (RECIBOS_PAGOS_DETALLES rwrd in recibosPagos.RECIBOS_PAGOS_DETALLES)
                        {
                            rwrd.FACTURAS = facturasDA.GetById(rwrd.ID_FACTURA);
                        }
                    }
                }
                return recibosPagos;
            }
            finally
            {
                if (InternalOpen && this.cnn.State != System.Data.ConnectionState.Closed)
                    this.cnn.Close();
            }
        }

        public List<RECIBOS_PAGOS> GetAll()
        {
            bool InternalOpen = false;
            try
            {
                #region Inicializar Metodo
                if (this.cnn == null)
                {
                    InternalOpen = true;
                    InicializarAdaptadores();
                }
                #endregion

                List<RECIBOS_PAGOS> list = new List<RECIBOS_PAGOS>();
                foreach (DataSet.V_RECIBOS_PAGOSRow rw in vAdapterMaster.GetData())
                {
                    list.Add(GetEntity(rw, null));
                }
                return list;
            }
            finally
            {
                if (InternalOpen && this.cnn.State != System.Data.ConnectionState.Closed)
                    this.cnn.Close();
            }
        }

        public List<RECIBOS_PAGOS> GetByFechas(DateTime value1, DateTime value2)
        {

            bool InternalOpen = false;
            try
            {
                #region Inicializar Metodo
                if (this.cnn == null)
                {
                    InternalOpen = true;
                    InicializarAdaptadores();
                }
                #endregion
                List<RECIBOS_PAGOS> list = new List<RECIBOS_PAGOS>();
                foreach (DataSet.V_RECIBOS_PAGOSRow rw in vAdapterMaster.GetDataByFechas(value1.Date, value2.Date))
                {
                    list.Add(GetEntity(rw, null));
                }
                return list;
            }
            finally
            {
                if (InternalOpen && this.cnn.State != System.Data.ConnectionState.Closed)
                    this.cnn.Close();
            }
        }

        public List<RECIBOS_PAGOS> GetByCliente(decimal id)
        {
            bool InternalOpen = false;
            try
            {
                #region Inicializar Metodo
                if (this.cnn == null)
                {
                    InternalOpen = true;
                    InicializarAdaptadores();
                }
                #endregion
                List<RECIBOS_PAGOS> list = new List<RECIBOS_PAGOS>();
                foreach (DataSet.V_RECIBOS_PAGOSRow rw in vAdapterMaster.GetDataByIdCliente(id))
                {
                    list.Add(GetEntity(rw, null));
                }
                return list;
            }
            finally
            {
                if (InternalOpen && this.cnn.State != System.Data.ConnectionState.Closed)
                    this.cnn.Close();
            }
        }

        public List<RECIBOS_PAGOS> GetByCliente(string value)
        {
            bool InternalOpen = false;
            try
            {
                #region Inicializar Metodo
                if (this.cnn == null)
                {
                    InternalOpen = true;
                    InicializarAdaptadores();
                }
                #endregion
                List<RECIBOS_PAGOS> list = new List<RECIBOS_PAGOS>();
                foreach (DataSet.V_RECIBOS_PAGOSRow rw in vAdapterMaster.GetDataByCliente(value.Trim()))
                {
                    list.Add(GetEntity(rw, null));
                }
                return list;
            }
            finally
            {
                if (InternalOpen && this.cnn.State != System.Data.ConnectionState.Closed)
                    this.cnn.Close();
            }
        }

        public List<RECIBOS_PAGOS> GetByNroDocumento(decimal nroDoc)
        {
            bool InternalOpen = false;
            try
            {
                #region Inicializar Metodo
                if (this.cnn == null)
                {
                    InternalOpen = true;
                    InicializarAdaptadores();
                }
                #endregion
                List<RECIBOS_PAGOS> list = new List<RECIBOS_PAGOS>();
                foreach (DataSet.V_RECIBOS_PAGOSRow rw in vAdapterMaster.GetDataByNroDocumento(nroDoc))
                {
                    list.Add(GetEntity(rw, null));
                }
                return list;
            }
            finally
            {
                if (InternalOpen && this.cnn.State != System.Data.ConnectionState.Closed)
                    this.cnn.Close();
            }
        }

        private RECIBOS_PAGOS GetEntity(DataSet.V_RECIBOS_PAGOSRow rwMaster, DataSet.V_RECIBOS_PAGOS_DETALLESDataTable tdDetaill)
        {
            RECIBOS_PAGOS reciboPago = null;
            if (rwMaster != null)
            {
                reciboPago = new RECIBOS_PAGOS();
                reciboPago.ID = rwMaster.ID;
                reciboPago.ID_CLIENTE = rwMaster.ID_CLIENTE;
                reciboPago.CLIENTES = new CLIENTES { ID = rwMaster.ID_CLIENTE, CLIENTE = rwMaster.CLIENTE, NOMBRE_COMERCIAL = rwMaster.NOMBRE_COMERCIAL, DIRECCION = rwMaster.DIRECCION };
                reciboPago.ID_VENDEDOR = rwMaster.ID_VENDEDOR;
                reciboPago.VENDEDORES = new VENDEDORES { ID = rwMaster.ID_VENDEDOR, VENDEDOR = rwMaster.VENDEDOR };
                reciboPago.ID_USUARIO = rwMaster.ID_USUARIO;
                reciboPago.USUARIOS = new USUARIOS { ID = rwMaster.ID_USUARIO, NOMBRE_USUARIO = rwMaster.USUARIO };
                reciboPago.ES_CONSIGNACION = rwMaster.ES_CONSIGNACION;
                reciboPago.NRO_DOCUMENTO = rwMaster.NRO_DOCUMENTO;
                reciboPago.FECHA = rwMaster.FECHA;
                if (!rwMaster.IsREFERENCIANull())
                    reciboPago.REFERENCIA = rwMaster.REFERENCIA;
                if (!rwMaster.IsOBSERVACIONESNull())
                    reciboPago.OBSERVACIONES = rwMaster.OBSERVACIONES;
                reciboPago.ACTIVO = rwMaster.ACTIVO;
                reciboPago.M_DESCUENTO = rwMaster.M_DESCUENTO;
                reciboPago.M_TOTAL = rwMaster.M_TOTAL;

                if (tdDetaill != null)
                {
                    foreach (DataSet.V_RECIBOS_PAGOS_DETALLESRow rw in tdDetaill)
                    {
                        if (rw != null)
                        {
                            RECIBOS_PAGOS_DETALLES RECIBOS_PAGOSdetalle = new RECIBOS_PAGOS_DETALLES();
                            RECIBOS_PAGOSdetalle.ID = rw.ID;
                            RECIBOS_PAGOSdetalle.ID_FACTURA = rw.ID_FACTURA;
                            RECIBOS_PAGOSdetalle.FACTURAS = new FACTURAS
                            {
                                ID = rw.ID_FACTURA,
                                ID_CONDICION = rw.ID_CONDICION,
                                ID_VENDEDOR = rw.ID_VENDEDOR,
                                CONDICIONES = new CONDICIONES { ID = rw.ID_CONDICION, CONDICION = rw.CONDICION },
                                VENDEDORES = new VENDEDORES { ID = rw.ID_VENDEDOR, VENDEDOR = rw.VENDEDOR },
                                FECHA_HORA = rw.FECHA_FACTURA,
                                M_TOTAL = rw.M_FACTURA,
                                M_PAGADO = rw.M_PAGADO_FACTURA,
                            };
                            RECIBOS_PAGOSdetalle.DESCUENTO = rw.DESCUENTO;
                            RECIBOS_PAGOSdetalle.X_DESCUENTO = rw.X_DESCUENTO;
                            RECIBOS_PAGOSdetalle.MONTO = rw.MONTO;
                            reciboPago.RECIBOS_PAGOS_DETALLES.Add(RECIBOS_PAGOSdetalle);
                        }
                    }
                }
            }
            return reciboPago;
        }

        public bool Anular(RECIBOS_PAGOS value)
        {
            bool InternalOpen = false;
            try
            {

                #region Inicializar Metodo
                if (this.cnn == null)
                {
                    InternalOpen = true;
                    InicializarAdaptadores();
                }
                #endregion

                #region Preparar RECIBOS_PAGOS encabezado
                this.entityMaster = AdapterMaster.GetDataByID(value.ID).FirstOrDefault();
                this.entityMaster.ACTIVO = false;
                this.AdapterMaster.Update(this.entitiesMaster);
                #endregion

                #region Ajustar Montos de Clientes
                DataSet.CLIENTESRow rwCliente = AdapterClientes.GetDataByID(value.ID_CLIENTE).FirstOrDefault();
                rwCliente.MONTO_ADEUDADO += value.M_TOTAL;
                AdapterClientes.Update(rwCliente);
                #endregion

                #region Preparar Detalle
                if (value.RECIBOS_PAGOS_DETALLES.Count > 0)
                {
                    entitiesDetaill = new DataSet.RECIBOS_PAGOS_DETALLESDataTable();
                    foreach (RECIBOS_PAGOS_DETALLES rw in value.RECIBOS_PAGOS_DETALLES)
                    {
                        this.entitiesFacturas = this.AdapterFacturas.GetDataByID(rw.ID_FACTURA);
                        this.entitiesFacturas.FirstOrDefault().M_PAGADO -= rw.MONTO;
                        this.AdapterFacturas.Update(this.entitiesFacturas);
                    }
                    this.AdapterFacturasDetalles.Update(this.entitiesFacturasDetalles);
                    this.AdapterDetaill.Update(this.entitiesDetaill);
                }
                else
                    throw new ArgumentException("Debe agregar facturas al detalle del recibo de pago");
                #endregion

                this.tr.Commit();

                value.ACTIVO = false;
            }
            catch
            {
                if (InternalOpen)
                    tr.Rollback();
                throw;
            }
            finally
            {
                if (InternalOpen && this.cnn.State != System.Data.ConnectionState.Closed)
                    this.cnn.Close();
            }
            return value.ACTIVO;
        }
    }
}
